#include "viewer.h"

#include <string>
#include <iostream>

#ifdef _MAC_OS_
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#endif

using namespace std;

Viewer::Viewer():
  _halfSize(0.5),
  _growing(true){
  }


Viewer::~Viewer(){

}


////////////////////////////////////////////////////////////////////////////////
// GL stuff

// initialize OpenGL context
void
Viewer::init(int w, int h){
  // background color
  glClearColor (0.0, 0.0, 0.0, 1.0);

  // viewport
  glViewport (0, 0, w, h);
    
  // square init
    _square.setDim(vec2f(0.5, 0.5));
    _square.setPosition(vec2f(0, 0));
    _square.setColor(vec3f(0, 1, 0));
    _square.setSpeed(vec2f(0, 0));
}

void
Viewer::reshape(int w, int h){
  glViewport (0, 0, w, h);
}


/*!
   callback to draw graphic primitives
   you may edit it if you want to change de drawing procedure (add new objects
   for example).
 */
void
Viewer::display() const{
  // clear current buffer
  glClear (GL_COLOR_BUFFER_BIT);

  // define projetion matrix
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity (); 
  glOrtho (-1.1, 1.1, -1.1, 1.1, -10, 10);

  // define model view matrix
  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity ();

  /////////////////////////////////////
  // Draw the primitives.
  //
  _square.draw();
  //
  // End of drawing
  /////////////////////////////////////

  glFlush();
}


void 
Viewer::updateScene () {
   _square.setPosition(_square.getPos().getX() + (+_square.getSpeed().getX())*0.001,
		       _square.getPos().getY() - (+_square.getSpeed().getY())*0.001);

   display();
}


////////////////////////////////////////////////////////////////////////////////
// Events

/*!
   callback to manage mouse : called when user press or release mouse button
   You can change in this function the way the user 
   interact with the system.
 */
void  
Viewer::mousePressed(int button, int state, int x, int y){
   std::string buttonName;

   switch(button){
   case GLUT_LEFT_BUTTON:
      buttonName = string("left");
      break;
   case GLUT_MIDDLE_BUTTON:
      buttonName = string("middle");
      break;
   case GLUT_RIGHT_BUTTON:
      buttonName = string("right");
      break;
   default:
      buttonName = string("invalid");
   }

	_square.setSpeed(vec2f((double) (1.1*(x-300))/300., (double) (1.1*(y-300))/300.));

   cout << "User " 
        << (state == GLUT_DOWN ? "press " : "release ")
        << buttonName.c_str()
        << " button in "
        << x 
        << ", "
        << y
        << endl;

   // request display refresh
   glutPostRedisplay(); 
}


 
 
/*!
   callback to manage mouse : called when user move mouse with button pressed
   You can change in this function the way the user 
   interact with the system.
 */
void
Viewer::mouseMoved(int x, int y){
     cout << "Mouse moved in "
        << x 
        << ", "
        << y
        << endl;

   // request display refresh
   glutPostRedisplay(); 
}


/*!
   callback to manage keyboard interactions
   You can change in this function the way the user 
   interact with the system.
 */
void
Viewer::keyPressed(unsigned char key, int x, int y){

}
